package com.dong.design.singleton;

import org.apache.commons.lang3.concurrent.BasicThreadFactory;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 单例模式——双检锁/双重校验锁（DCL，即 double-checked locking）
 * JDK 版本：JDK1.5 起
 * 是否 Lazy 初始化：是
 * 是否多线程安全：是
 * 实现难度：较复杂
 * 描述：这种方式采用双锁机制，安全且在多线程情况下能保持高性能。
 * getInstance() 的性能对应用程序很关键。
 *
 * @author jianyang206881
 * @date 2018/2/24
 */
public class DCLSingleton {
    private static DCLSingleton instance;

    private DCLSingleton() {

    }

    public static DCLSingleton getInstance() {
        if (instance == null) {
            synchronized (DCLSingleton.class) {
                if (instance == null) {
                    instance = new DCLSingleton();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) throws InterruptedException {

        /*
         * <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
         <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-lang3</artifactId>
         <version>3.3.2</version>
         </dependency>
         */
        ThreadFactory namedThreadFactory = new BasicThreadFactory.Builder()
                .namingPattern("lazy-singleton-pool-%d").daemon(true).build();

        ThreadPoolExecutor singlePool = new ThreadPoolExecutor(3, 10,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(2), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());

        for (int i = 0; i < 20; i++) {
            singlePool.execute(() -> {
                DCLSingleton newInstance = DCLSingleton.getInstance();
                System.out.println(Thread.currentThread().getName() + ":" + newInstance + "-" + Thread.activeCount());
            });
        }

        singlePool.shutdown();

    }

}
